package com.itheima.es.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.es.config.SkuConfig;
import com.itheima.es.entity.PageResult;
import com.itheima.es.entity.QueryPageBean;
import com.itheima.es.entity.Result;
import com.itheima.es.mapper.SkuMapper;
import com.itheima.es.pojo.GoodInfo;
import com.itheima.es.pojo.Sku;

import com.itheima.es.service.SkuService;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpHost;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.unit.Fuzziness;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

@Service
@Transactional
public class SkuServiceImpl extends ServiceImpl<SkuMapper, Sku> implements SkuService {
    @Autowired
    private RestHighLevelClient restHighLevelClient;
    //分页查询
    @Override
    public PageResult search(QueryPageBean queryPageBean) {
        // 1.构建bool条件对象
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        //2.判断是否条件查询
        if(StringUtils.isBlank(queryPageBean.getQueryString())){
            //查询所有
            MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();
            boolQueryBuilder.must(matchAllQueryBuilder);
        }else{
            //有条件查询
            MatchQueryBuilder matchQuery = QueryBuilders.matchQuery("name", queryPageBean.getQueryString());
            boolQueryBuilder.must(matchQuery);
        }
        //价格区间过滤查询
        if(queryPageBean.getMinPrice()>=0){
            RangeQueryBuilder queryBuilderByPrice = QueryBuilders.rangeQuery("price").
                    gte(queryPageBean.getMinPrice()).
                    lte(queryPageBean.getMaxPrice());
            boolQueryBuilder.filter(queryBuilderByPrice);

        }
        PageResult pageResult = queryList(boolQueryBuilder, queryPageBean);
        return pageResult;

    }



    public PageResult   queryList(QueryBuilder queryBuilder,QueryPageBean queryPageBean){
        List<Sku> list = new ArrayList<>();
        try {
            //1.创建SearchSourceBuilder对象
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

            //1.添加查询条件QueryBuilders(排序，分页等)

            //1.1添加排序查询
            int sort = queryPageBean.getSort();
            //设置初始化
            sort = 0;
            switch (sort){
                //销量排序
                case 1:searchSourceBuilder.sort("sale_num",SortOrder.ASC);
                break;
                //价格排序
                case 2:searchSourceBuilder.sort("price",SortOrder.ASC);
                break;
                //创建时间排序
                case 3:searchSourceBuilder.sort("create_time",SortOrder.ASC);
                break;
                //评论排序
                case 4 :
                    searchSourceBuilder.sort("comment_num",SortOrder.DESC);
            }


            //1.2分页查询
            int currentPage = queryPageBean.getCurrentPage();
            int pageSize = queryPageBean.getPageSize();
            int from = (currentPage-1)*pageSize;
            searchSourceBuilder.from(from);
            searchSourceBuilder.size(pageSize);

            //1.3高亮设置
            //设置高亮三要素
            HighlightBuilder highlight = SearchSourceBuilder.highlight();
            //高亮显示的域
            HighlightBuilder name = highlight.field("name");
            //高亮显示的前缀<font color='pink'></font>
            highlight.preTags("<font color='pink'>");
            //高亮显示的后缀
            highlight.postTags("</font>");
            searchSourceBuilder.highlighter(highlight);
            searchSourceBuilder.query(queryBuilder);


            //2.创建SearchRequest对象，并制定索引库名称
            SearchRequest request = new SearchRequest("sku");

            //3.添加SearchSourceBuilder对象到SearchRequest对象source中
            request.source(searchSourceBuilder);

            //4.发起请求，得到结果
            SearchResponse searchResponse = restHighLevelClient.search(request, RequestOptions.DEFAULT);

            //5.解析结果SearchResponse
            SearchHits hits = searchResponse.getHits();
            //5.1获取总条数
            long totalHits = hits.getTotalHits().value;

            System.out.println("总条数是："+totalHits);
            //5.2获取SearchHits数组，并遍历
            SearchHit[] searchHits = hits.getHits();
            for (SearchHit hit : searchHits) {
                //5.2.1获取其中的_source，是JSON数据
                String jsonString = hit.getSourceAsString();
                //5.2.2把——source反序列化为User对象
                Sku sku = JSON.parseObject(jsonString, Sku.class);

                //解析高亮数据
                HighlightField highlightField = hit.getHighlightFields().get("name"); // get("高亮显示域名称")
                Text[] fragments = highlightField.getFragments();
                String hilightName = StringUtils.join(fragments);//将数组以某种拼接符拼接成新的字符串
                // 判断如果是可以获取到数据则更新到用户对象中
                if (StringUtils.isNotBlank(hilightName)) {
                    sku.setName(hilightName);
                }
                System.out.println("sku = " + sku);
                list.add(sku);
            }
            return new PageResult(totalHits,list);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 分页查询
     * @param cuurrentPage 当前页码
     * @param pageSze 每页的条数
     * @return
     */
    public List<Sku> findPage(int cuurrentPage,int pageSze){
        Page<Sku> page = page(new Page<>(cuurrentPage, pageSze));
        List<Sku> records = page.getRecords();
        return records;
    }
}
